package com.yugu.park.config;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.Signature;
import java.security.SignatureException;
import java.util.Base64;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wechat.pay.contrib.apache.httpclient.auth.PrivateKeySigner;
import com.wechat.pay.contrib.apache.httpclient.auth.Verifier;
import com.wechat.pay.contrib.apache.httpclient.auth.WechatPay2Credentials;
import com.wechat.pay.contrib.apache.httpclient.cert.CertificatesManager;
import com.wechat.pay.contrib.apache.httpclient.exception.HttpCodeException;
import com.wechat.pay.contrib.apache.httpclient.exception.NotFoundException;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import com.wechat.pay.contrib.apache.httpclient.util.PemUtil;

import lombok.Data;

@Component
@Data
@ConfigurationProperties(value = "v3")
public class WxPayConfig {
	//appId
    private String appId;
    //商户id
    private String merchantId;
    //证书序列号
    private String merchantSerialNumber;
    //私钥路径
    private String certKeyPath;
    //商户秘钥
    private String apiV3Key;
    //回调通知支付地址
    private String wxnotify;
    //回调通知退款地址
    private String wxrefund;
    /*支付通知和退款通知给服务器的回调 请求头验签*/
	public boolean signVerify(String serialNumber, String message, String signature) {
		try {
			PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream(certKeyPath));
			// 获取证书管理器实例
			CertificatesManager certificatesManager = CertificatesManager.getInstance();
			// 向证书管理器增加需要自动更新平台证书的商户信息
			certificatesManager.putMerchant(merchantId,
					new WechatPay2Credentials(merchantId,
							new PrivateKeySigner(merchantSerialNumber, merchantPrivateKey)),
					apiV3Key.getBytes(StandardCharsets.UTF_8));
			// 从证书管理器中获取verifier
			Verifier verifier = certificatesManager.getVerifier(merchantId);
			return verifier.verify(serialNumber, message.getBytes(StandardCharsets.UTF_8), signature);
		} catch (HttpCodeException | NotFoundException | IOException | GeneralSecurityException e) {
			e.printStackTrace();
		}
		return false;
	}
	/*支付通知和退款通知给服务器的回调 解密报文*/
	public String decryptOrder(String body) {
		try {
			AesUtil util = new AesUtil(apiV3Key.getBytes(StandardCharsets.UTF_8));
			ObjectMapper objectMapper = new ObjectMapper();
			JsonNode node = objectMapper.readTree(body);
			JsonNode resource = node.get("resource");
			String ciphertext = resource.get("ciphertext").textValue();
			String associatedData = resource.get("associated_data").textValue();
			String nonce = resource.get("nonce").textValue();
			return util.decryptToString(associatedData.getBytes("utf-8"), nonce.getBytes("utf-8"), ciphertext);
		} catch (JsonProcessingException | UnsupportedEncodingException | GeneralSecurityException e) {
			e.printStackTrace();
		}
		return null;
	}
	public String sign(byte[] message) {
		try {
			PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(new FileInputStream(certKeyPath));
			Signature sign = Signature.getInstance("SHA256withRSA");
			sign.initSign(merchantPrivateKey);
			sign.update(message);
			return Base64.getEncoder().encodeToString(sign.sign());
		} catch (InvalidKeyException e) {
			e.printStackTrace();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		} catch (SignatureException e) {
			e.printStackTrace();
		}
		return null;
	}
}
